#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "serverenum.h"
#include "command.h"
#include "functionhelper.h"
//#include "assistantwidgets.h"
#include <QDrag>
#include <QDragEnterEvent>
#include <QMimeData>
#include <QMainWindow>
#include <QLabel>
#include <QTimerEvent>
#include <QPixmap>
#include <QImage>
#include <QScrollArea>
#include <QThread>
#include <QFileDialog>
#include <QMessageBox>
#include <QLineEdit>
#include <QStackedWidget>
#include <QDebug>

#define GRIDVIEW_WIDGET_WIDTH 972
#define PREVIEW_MODE_MAP   0
#define PREVIEW_MODE_LIST  1

MainWindow::MainWindow(QWidget *parent, ServerEnum *servers) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    this->servers = servers;
    vmWidth = 1280;
    vmHeight = 720;

    dispWidth = ITEM_PIC_WIDTH;
    dispHeight = ITEM_PIC_WIDTH * 1.0 * vmHeight / vmWidth;

    //subWinList.clear();
    //lastHoverItem = NULL;
    //groupPreviewData->vms.clear();

    vmsManager = new VmsManager(servers, this);
    groupsManager = new GroupsManager(vmsManager, servers, this);
    accountControl = new UserAccessControlClient(this);
    groupWidget = new GroupWidget(groupsManager, this);
    loginDialog = new LoginDialog(this);
    bandPhoneDialog = new BandPhoneDialog(this);

    setupMainUI();

    connect(createBtn, SIGNAL(clicked()), this, SLOT(onMassCreateBtnClicked()));
    connect(removeBtn, SIGNAL(clicked()), this, SLOT(onMassRemoveBtnClicked()));
    connect(addVmsToGroupBtn, SIGNAL(clicked()), this, SLOT(onAddVmsToGroupBtnClicked()));
    connect(selectAllBtn, SIGNAL(clicked()), this, SLOT(onSetSelectAll()));
    connect(vmsManager, SIGNAL(vmAdded(VmInfo*)), this, SLOT(onAddPreviewWidget(VmInfo*)), Qt::QueuedConnection);
    connect(vmsManager, SIGNAL(vmAdded(VmInfo*)), groupWidget, SLOT(onAddGroupVm(VmInfo*)), Qt::QueuedConnection);
    connect(vmsManager, SIGNAL(vmRemoved(const char *, const int)), this, SLOT(onRemovePreviewWidget(const char *, const int)), Qt::QueuedConnection);
    connect(vmsManager, SIGNAL(vmRemoved(const char *, const int)), groupWidget, SLOT(onRemoveGroupVm(const char *, const int)), Qt::QueuedConnection);
    connect(vmsManager, SIGNAL(vmStatusChanged(const char *, const int, const int)), this, SLOT(onUpdatePreviewStatus(const char *, const int, const int)), Qt::QueuedConnection);
    connect(groupWidget, SIGNAL(vmGroupChanged(int)), this, SLOT(onVmGroupChanged(int)));
    connect(tasksTrace, SIGNAL(taskStatusChanged(const int, const int, QByteArray)), this, SLOT(onTaskStatusChanged(const int, const int, QByteArray)), Qt::QueuedConnection);
    connect(this, SIGNAL(removeTask(const int)), tasksTrace, SLOT(onRemoveTask(const int)));
    connect(this, SIGNAL(sendCommand(const char*,int,const QString &, QObject *)),
        vmsManager, SLOT(doOperation(const char*,int,const QString &, QObject *)), Qt::QueuedConnection);
    connect(groupWidget, SIGNAL(vmAdded(VmInfo *)), this, SLOT(onAddPreviewWidget(VmInfo *)));
    connect(groupWidget, SIGNAL(vmRemoved(const char *, const int)), this, SLOT(onRemovePreviewWidget(const char *, const int)));
    connect(accountControl, SIGNAL(userAuthStateChanged(int)), this, SLOT(onUserAuthStateChanged(int)));

    titleBar->setTitle(tr("XL4Update"));

    vmsManager->start();

    //accountControl->bootStart();
}

#include <windows.h>
#include <QWindow>
#define FRAME_MAX_WIDTH   1330
#define FRAME_MAX_HEIGHT  784

void MainWindow::setupMainUI()
{
    this->resize(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT);
    this->setMinimumSize(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT);
    this->setObjectName("MainWindow");

    HWND hwnd = reinterpret_cast<HWND>(this->winId());
    LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
    lStyle &= ~(WS_CAPTION | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
    SetWindowLong(hwnd, GWL_STYLE, lStyle);
    windowHandle()->reportContentOrientationChange(Qt::PrimaryOrientation);

    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint | Qt::Window);
    setMouseTracking(true);

    ui->setupUi(this);

    this->setStyleSheet(
                "QWidget#MainWindow { border: 1px solid #1e1e2e; background: rgb(58,57,54);}"
                "QWidget {"
                "    color: rgb(90, 90, 90);"
                "    font:13px \"Microsoft Yahei\",\"Arial\",\"宋体\",\"Helvetica\";"
                "}"
                "#topBox {"
                "                        border: 1px solid rgb(208,208,208);"
                "                        background: rgb(243,243,243);"
                "                        margin-left: -1px;"
                "}"
                "#bottomBox {"
                "                        border: 1px solid rgb(189,189,189);"
                "                        background: rgb(243,243,243);"
                "                        margin-left: -1px;"
                "}"
                "#gridWidgetContents {"
                "                        border: 1px solid #fff;"
                "                        border-right-color: rgb(189,189, 189);"
                "                        background: #fff;"
                "}"
                "#gridViewWidget { margin-top: 1px; }"
                "QLabel#titleBarSplitLine { border: 1px solid #ebebeb; }"
                "QToolButton#maxButton {border-image:url(:/maximum.png); width:16px; height:16px;}"
                "QToolButton#maxButton:pressed {border-image:url(:/maximum_pressed.png);width:16px;height:16px;}"
                "QToolButton#maxButton:hover:!pressed {border-image:url(:/maximum_hover.png);width:16px;height:16px;}"
                "QToolButton#restoreButton {border-image:url(:/restore.png); width:16px; height:16px;}"
                "QToolButton#restoreButton:pressed {border-image:url(:/restore_pressed.png);width:16px;height:16px;}"
                "QToolButton#restoreButton:hover:!pressed {border-image:url(:/restore_hover.png);width:16px;height:16px;}"
                "QToolButton#minButton {border-image:url(:/minimize.png); width:16px; height:16px;}"
                "QToolButton#minButton:pressed {border-image:url(:/minimize_pressed.png);width:16px;height:16px;}"
                "QToolButton#minButton:hover:!pressed {border-image:url(:/minimize_hover.png);width:16px;height:16px;}"
                "QToolButton#closeButton {border-image:url(:/close.png); width:16px; height:16px;}"
                "QToolButton#closeButton:pressed {border-image:url(:/close_pressed.png);width:16px;height:16px;}"
                "QToolButton#closeButton::hover:!pressed {border-image: url(:/close_hover.png);width:16px;height:16px;}"
                "QPushButton#dialogCancelButton,QPushButton#dialogOkButton {"
                "   border: 1px solid #c9c9c9; "
                "   background-color: #ffffff; "
                "   font: 14px \"Microsoft Yahei\";"
                "   border-radius: 1px;"
                "   text-align: center;"
                "   width: 90px;"
                "   height: 30px;"
                "}"
                "QPushButton#dialogCancelButton:hover:!pressed, QPushButton#dialogOkButton:hover:!pressed { "
                "   background-color: #f5f5f5;"
                "}"
                "QPushButton#dialogCancelButton:pressed, QPushButton#dialogOkButton:pressed { "
                "   background-color: #e8e8e8;"
                "}"
                "QListView#dialogListView {"
                "  border: 1px solid #e4e4e4;"
                "}"
                "QListView#dialogListView::item {"
                "  border: 1px solid rgb(189,189,189);"
                "  margin-top: -1;"
                "  border-left-color: #fff;"
                "  min-height: 30;"
                "}"
                "QListView::item:hover {"
                "  color: #323232; "
                "  background: rgb(250, 250, 250);"
                "}"
                "QListView::item:selected:active {"
                "  color: #323232; "
                "  background: rgb(245, 245, 245);"
                "}"
                "QListView::item:selected:!active {"
                "  color: #323232; "
                "  background: rgb(245, 245, 245);"
                "}"
                "QScrollArea { border: 1px solid #c9c9c9; }"
                "QScrollBar:vertical {"
                "    background-color: #fff;"
                "    width: 8px;"
                "    margin: 0;"
                "}"
                "QScrollBar::handle:vertical {"
                "    border: 1px solid #c9c9c9;"
                "    border-radius: 4px;"
                "    background: #acacac;"
                "}"
                "QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical,"
                "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {"
                "    height: 0px;"
                "    background: transparent;"
                "}"
                "QMessageBox { border: 0px; background: #fff; }"
                );

    titleBar = new TitleBarWidget(this);
    titleBar->setFixedHeight(TITLE_HEIGHT);
    QGridLayout *titleAreaLayout = new QGridLayout(ui->titleBarArea);
    titleAreaLayout->addWidget(titleBar, 0, 0, Qt::AlignTop);
    titleAreaLayout->setMargin(0);
    titleAreaLayout->setSpacing(0);

    this->setMouseTracking(true);
    ui->centralWidget->setMouseTracking(true);
    ui->gridViewWidget->setMouseTracking(true);
    //ui->gridViewArea->setMouseTracking(true);
    //ui->scrollAreaWidgetContents->setMouseTracking(true);

    vmsMapView = new VmsMapView(this);
    vmsMapView->setMouseTracking(true);
    vmsListView = new VmsListView(this);
    vmsListView->setObjectName("vmsListView");
    //first is show map view page
    vmsGroupView = (PreviewAreaBase *)vmsMapView;

    QScrollArea *scrollArea = new QScrollArea;
    scrollArea->setObjectName("previewScrollArea");
    scrollArea->setStyleSheet("QWidget#previewScrollArea, QWidget#vmsListView {border: 1px solid #97979780;"
                              "     border-left-color: #fff;"
                              "     border-top-color: #fff;"
                              "     border-bottom-color: #fff;"
                              "} "
                              "QScrollArea { border: 1px solid #c9c9c9; }"
                              "QScrollBar:vertical {"
                              "    background-color: #fff;"
                              "    width: 8px;"
                              "    margin: 0;"
                              "}"
                              "QScrollBar::handle:vertical {"
                              "    border: 1px solid #c9c9c9;"
                              "    border-radius: 4px;"
                              "    background: #acacac;"
                              "}"
                              "QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical,"
                              "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {"
                              "    height: 0px;"
                              "    background: transparent;"
                              "}"
                              );
    scrollArea->setContentsMargins(0, 0, 0, 0);
    scrollArea->setMouseTracking(true);
    scrollArea->setWidget(vmsMapView);
    scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    scrollArea->setAutoFillBackground(true);
    QPalette scrollAreaBgpal = scrollArea->palette();
    scrollAreaBgpal.setColor (QPalette::Window, QColor(255, 255, 255));
    scrollArea->setPalette(scrollAreaBgpal);

    ui->gridWidgetContents->setContentsMargins(0, 0, 0, 0);
    QGridLayout *gridViewLayout = new QGridLayout (ui->gridWidgetContents);
    gridViewLayout->setMargin(0);
    gridViewLayout->setSpacing(0);

    previewStackedWidget = new QStackedWidget(this);
    previewStackedWidget->setObjectName("previewStackedWidget");
    previewStackedWidget->setMouseTracking(true);
    previewStackedWidget->setContentsMargins(0, 0, 0, 0);
    previewStackedWidget->layout()->setSpacing(0);
    previewStackedWidget->layout()->setMargin(0);
    previewStackedWidget->addWidget(scrollArea);
    previewStackedWidget->addWidget(vmsListView);
    //gridViewLayout->addWidget(previewStackedWidget, 0, 0, 1, 1);
    previewStackedWidget->setCurrentIndex(0);

    ui->groupViewWidget->setContentsMargins(0, 0, 0, 0);
    ui->gridViewWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    ui->groupViewWidget->setFixedWidth(LEFT_PANE_BOX_WIDTH);
    QVBoxLayout *groupViewLayout = new QVBoxLayout(ui->groupViewWidget);
    groupViewLayout->addWidget(groupWidget);
    groupViewLayout->setMargin(0);
    groupViewLayout->setSpacing(0);

    tasksTrace = new OperationTasksTrace(this);

    //connect(titleBar, SIGNAL(showMassOperationClicked()), this, SLOT(onShowMassOperationClicked()));
    //connect(titleBar, SIGNAL(showGroupOperationClicked()), this, SLOT(onShowGroupOperationClicked()));

    btnListPreview = new QPushButton(tr("列表模式"), this);
    btnListPreview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    btnListPreview->setObjectName("btnListPreview");
    btnListPreview->setCheckable(true);
    btnMapPreview = new QPushButton(tr("视图模式"), this);
    btnMapPreview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    btnMapPreview->setObjectName("btnMapPreview");
    btnMapPreview->setCheckable(true);
    QWidget *previewModeSwitch = new QWidget();
    previewModeSwitch->setFixedSize(145, 32);
    QHBoxLayout *previewModeSwitchLayout = new QHBoxLayout(previewModeSwitch);
    previewModeSwitchLayout->addWidget(btnMapPreview);
    previewModeSwitchLayout->addWidget(btnListPreview);
    previewModeSwitchLayout->setMargin(0);
    previewModeSwitchLayout->setSpacing(0);
    previewModeSwitch->setStyleSheet(""
        "QPushButton { "
        "   background-color: white;"
        "   border: 1px solid #d0d0d0; "
        "   margin-left: 0px;"
        "   margin-right: 0px;"
        "   padding-left: 4px; "
        "   padding-right: 4px;"
        "}"
        "QPushButton#btnListPreview {"
        "   border-top-right-radius: 2px;"
        "   border-bottom-right-radius: 2px;"
        "   margin-left: -2;"
        "}"
        "QPushButton#btnMapPreview {"
        "   border-top-left-radius: 2px;"
        "   border-bottom-left-radius: 2px;"
        "}"
        "QPushButton#btnListPreview:checked, QPushButton#btnMapPreview:checked { "
        "   color: white;"
        "   background-color: rgb(14,198,162);"
        "   border: 1px solid #d0d0d0; "
        "}");
    btnListPreview->setChecked(false);
    btnMapPreview->setChecked(true);
    connect (btnListPreview, SIGNAL(clicked()), this, SLOT(onPreviewModeSwitched()));
    connect (btnMapPreview, SIGNAL(clicked()), this, SLOT(onPreviewModeSwitched()));

    selectAllBtn = new QToolBarMenuButton(tr("全选"), this);
    selectAllBtn->setFixedWidth(70);
    createBtn = new QToolBarMenuButton(tr("创建"), this);
    createBtn->setFixedWidth(70);
    addVmsToGroupBtn = new QToolBarMenuButton(tr("添加模拟器到组"), this);
    addVmsToGroupBtn->setFixedWidth(110);
    hSpacerLabel = new QLabel();
    hSpacerLabel->setFixedSize(30, 1);
    QGridLayout *btnsLayout = new QGridLayout();
    btnsLayout->addWidget(hSpacerLabel, 0, 0, 1, 1);
    btnsLayout->addWidget(addVmsToGroupBtn, 0, 1, 1, 1);
    btnsLayout->addWidget(createBtn, 0, 1, 1, 1);
    btnsLayout->setSpacing(0);
    btnsLayout->setMargin(0);
    addVmsToGroupBtn->hide();
    removeBtn = new QToolBarMenuButton(tr("删除"), this);
    removeBtn->setFixedWidth(70);
    QHBoxLayout *topBoxLayout = new QHBoxLayout(ui->topBox);
    topBoxLayout->addSpacing(20);
    topBoxLayout->addWidget(previewModeSwitch, 0, Qt::AlignLeft);
    topBoxLayout->addWidget(selectAllBtn, 0, Qt::AlignRight);
    topBoxLayout->addLayout(btnsLayout);
    topBoxLayout->addSpacing(30);
    topBoxLayout->addWidget(removeBtn);
    topBoxLayout->addSpacing(20);
    topBoxLayout->setMargin(0);

    // operationTipsBar
    operationTipsBar = new QWidget(this);
    operationTipsBar->setObjectName("tipsBar");
    operationTipsBar->setFixedHeight(30);
    operationTipsBar->setStyleSheet("QWidget#tipsBar {"
                                    "border: 1px solid rgb(208, 201, 248); "
                                    "margin-top: -1px; "
                                    "margin-left: -1px; "
                                    "background: rgb(255, 255, 225);"
                                    "}" );
    tipsBarLabel = new QLabel("sseeeee", this);
    tipsBarLabel->setStyleSheet("font-size:14px; color: black;");
    tipsBarLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);

    tipsAnimation = new QPropertyAnimation(this, "size");
    //connect (tipsAnimation, SIGNAL (finished ()),
    //         this, SLOT (hideAniomationFinished ()));

    QToolButton *tipsBarCloseBtn = new QToolButton(this);
    tipsBarCloseBtn->setStyleSheet( "QToolButton {border-image: url(:/tipsbar_close.png);}");
    connect(tipsBarCloseBtn, SIGNAL(clicked()), this, SLOT(onTipsBarCloseBtnClicked()));
    QHBoxLayout *tipsBarLayout = new QHBoxLayout(operationTipsBar);
    tipsBarLayout->addSpacing(10);
    tipsBarLayout->addWidget(tipsBarLabel);
    tipsBarLayout->addStretch(1);
    tipsBarLayout->addWidget(tipsBarCloseBtn);
    tipsBarLayout->addSpacing(20);
    tipsBarLayout->setMargin(0);
    operationTipsBar->hide();

    gridViewLayout->addWidget(operationTipsBar, 0, 0, 1, 1);
    gridViewLayout->addWidget(previewStackedWidget, 1, 0, 1, 1);
    // set bottom box
    createMassOpsBox();

    connect(titleBar, SIGNAL(maximumBtnClicked()), this, SLOT(showMaximized()));
    connect(titleBar, SIGNAL(restoreBtnClicked()), this, SLOT(showNormal()));
    connect(titleBar, SIGNAL(minimizeBtnClicked()), this, SLOT(showMinimized()));
    connect(titleBar, SIGNAL(closeClicked()), this, SLOT(slotClose()));
    connect(titleBar, SIGNAL(loginButtonClicked()), this, SLOT(showLoginDialog()));
    connect(titleBar, SIGNAL(quitLoginButtonClicked()), this, SLOT(quitLogin()));
    connect(titleBar, SIGNAL(moveWindowTo(QPoint)), this, SLOT(setWindowPos(QPoint)));
    connect(titleBar, SIGNAL(bandPhoneClicked(int)), this, SLOT(onShowBandPhone(int)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onShowMassOperationClicked()
{
    titleBar->groupOperationMenu->hide();
    titleBar->massOperationMenu->show();
}

void MainWindow::onShowGroupOperationClicked()
{
    titleBar->groupOperationMenu->show();
    titleBar->massOperationMenu->hide();
}

void MainWindow::showLoginDialog(int index)
{
    loginDialog->setPage(index);
    loginDialog->exec2();
    loginDialog->close();
}

void MainWindow::quitLogin()
{
    loginDialog->logout();
}

void MainWindow::onShowBandPhone(int type)
{
    bandPhoneDialog->setCurrentIndex(type);
    bandPhoneDialog->clear();
    bandPhoneDialog->exec2();
    bandPhoneDialog->close();
}

void MainWindow::onGroupLaunchBtnClicked()
{
    QList<VmInfo *> selectedVms = vmsGroupView->getSelectedVms();
    if (!selectedVms.count()) {
        MEmuMsgBox msgBox(tr("逍遥安卓"), tr("没有选中模拟器，请勾选您需要启动的模拟器！"), this);
        QPushButton *okBtn = msgBox.addButton(tr("确定"), QMessageBox::ActionRole);
        okBtn->setObjectName("dialogOkButton");
        msgBox.setCenterButtons(true);
        msgBox.exec2();
        msgBox.close();
        return;
    }

    this->groupsManager->groupVmsOperation(this->groupWidget->currentGroup(), "LaunchVm", "-b", selectedVms);
}

void MainWindow::onGroupCloseBtnClicked()
{
    QList<VmInfo *> selectedVms = vmsGroupView->getSelectedVms();
    if (!selectedVms.count()) {
        MEmuMsgBox msgBox(tr("逍遥安卓"), tr("没有选中模拟器，请勾选您需要关闭的模拟器！"), this);
        QPushButton *okBtn = msgBox.addButton(tr("确定"), QMessageBox::ActionRole);
        okBtn->setObjectName("dialogOkButton");
        msgBox.setCenterButtons(true);
        msgBox.exec2();
        msgBox.close();
        return;
    }

    this->groupsManager->groupVmsOperation(this->groupWidget->currentGroup(), "ShutdownVm", "", selectedVms);
    //Command *cmd = new Command();
    //cmd->slotSendCommand(servers->localServer.ipaddr,
    //                 servers->localServer.consolePort,
    //                 "LaunchVm##MEmu");
    //delete cmd;
/*    OperateWindow *ow = new OperateWindow(this,
                                          servers->localServer.ipaddr,
                                          servers->localServer.memuBasePort,
                                          servers->localServer.vms[0]->sm->data());
                                          //servers->localServer.buffPtr[0]);
    ow->showNormal();*/
}

void MainWindow::onGroupInstallAppBtnClicked()
{
    QList<VmInfo *> selectedVms = vmsGroupView->getSelectedVms(true);
    if (!selectedVms.count()) {
        MEmuMsgBox msgBox(tr("逍遥安卓"), tr("未选中启动模拟器，请启动模拟器，并勾选后，再操作！"), this);
        QPushButton *okBtn = msgBox.addButton(tr("确定"), QMessageBox::ActionRole);
        okBtn->setObjectName("dialogOkButton");
        msgBox.setCenterButtons(true);
        msgBox.exec2();
        msgBox.close();
        return;
    }

    QString file = QFileDialog::getOpenFileName(this, tr("请选择需要安装的安卓应用"), "", tr("Android安装包 (*.apk)"), 0);
    if (file.isEmpty())
        return;

    onShowOperationTips(tr("正在批量安装应用%1").arg(file));
    this->groupsManager->groupVmsOperation(this->groupWidget->currentGroup(), "InstallApk", file, selectedVms);
}

void MainWindow::onGroupUninstallAppBtnClicked()
{
    QList<VmInfo *> selectedVms = vmsGroupView->getSelectedVms(true);
    if (!selectedVms.count()) {
        MEmuMsgBox msgBox(tr("逍遥安卓"), tr("未选中启动模拟器，请启动模拟器，并勾选后，再操作！"), this);
        QPushButton *okBtn = msgBox.addButton(tr("确定"), QMessageBox::ActionRole);
        okBtn->setObjectName("dialogOkButton");
        msgBox.setCenterButtons(true);
        msgBox.exec2();
        msgBox.close();
        return;
    }

    OperationMsgBox msgBox(tr("删除的安卓应用"), tr("请输入需要删除的安卓应用包名:\n"), this, OperationMsgBox::OPERATOR_TYPE_ONLY_INPUT);
    msgBox.setCenterButtons(true);
    QPushButton *okBtn = msgBox.addButton(tr("删除"), QMessageBox::AcceptRole);
    okBtn->setObjectName("dialogOkButton");
    msgBox.exec2();
    bool isConfirmed = (msgBox.clickedButton() == okBtn);
    QString uninstallApp = msgBox.inputLineEdit->text();
    msgBox.close();
    if (!isConfirmed || uninstallApp.isEmpty())
        return;

    onShowOperationTips(tr("正在批量卸载应用%1").arg(uninstallApp));
    this->groupsManager->groupVmsOperation(this->groupWidget->currentGroup(), "UninstallApk", uninstallApp, selectedVms);
}

void MainWindow::onMassCreateBtnClicked()
{
    CreateVmDialog massCreateVmDialog(this);
    massCreateVmDialog.exec2();
    int number = massCreateVmDialog.getNumber();
    if (massCreateVmDialog.result() != QDialog::Accepted || !number)
        return;

    GroupData *data = groupsManager->getData(groupWidget->currentGroup());
    if (!data)
        return;

    HostServer *sv = servers->getServer(data->ipaddr, HOST_SERVER_PORT_LISTEN_ALL);
    if (!sv)
        return;

    for (int i = 0; i < number; i++)
        emit sendCommand(sv->ipaddr, sv->consolePort, QString("CreateVm"));
}

void MainWindow::onMassRemoveBtnClicked()
{
    QList<VmInfo *> selectedVms = vmsGroupView->getSelectedVms();
    QString tipWords = selectedVms.count() ? tr("您确定删除所有选中的逍遥安卓模拟器吗？\n") : tr("当前没有选中的模拟器，请选中后再操作！");
    MEmuMsgBox msgBox(tr("逍遥安卓"), tipWords, this);
    QPushButton *okBtn = msgBox.addButton(tr("确定"), QMessageBox::ActionRole);
    okBtn->setObjectName("dialogOkButton");
    QPushButton *cancelBtn = msgBox.addButton("取消", QMessageBox::RejectRole);
    cancelBtn->setObjectName("dialogCancelButton");
    msgBox.setCenterButtons(true);
    msgBox.exec2();
    msgBox.close();
    if (okBtn != msgBox.clickedButton() || !selectedVms.count())
        return;

    // if in custom group not real delete it
    bool isOnlyMapping = (groupWidget->currentViewMode() == GroupWidget::VIEW_MODE_CUSTOM_GROUP &&
            groupWidget->currentGroup() != VM_GROUP_ALL );

    foreach (VmInfo *vm, selectedVms) {
        if (isOnlyMapping)
            vmsGroupView->removeItem(vm->ipaddr, vm->vmPort);
        else {
            HostServer *sv = servers->getServer(vm->ipaddr, HOST_SERVER_PORT_LISTEN_ALL);
            if (!sv)
                return;
            emit sendCommand(sv->ipaddr, sv->consolePort,
                                        QString("RemoveVm##%1").arg(vm->vmName));
        }
    }
}

void MainWindow::onAddVmsToGroupBtnClicked()
{
    int groupId = groupWidget->currentGroup();
    if (groupId == INVALID_VM_GROUP)
        return;

    AddVmsToGroupDialog addVmsDialog(groupsManager, groupId, w);
    addVmsDialog.exec2();

    if (addVmsDialog.result() != QDialog::Accepted)
        return;

    QList<VmInfo *> itemList = addVmsDialog.getCheckedVms();
    groupsManager->addVms(groupId, itemList);
}

void MainWindow::onShowOperationTips(const QString &text, int delay)
{
    operationTipsBar->show();
    tipsBarLabel->setText(text);

/*    tipsAnimation->setDuration(150);
    tipsAnimation->setStartValue(QSize(vmsMapView->width(), 1));
    tipsAnimation->setEndValue(QSize(vmsMapView->width(), 30));
    if (tipsAnimation->state () != QAbstractAnimation::Running)
        tipsAnimation->start();*/

/*    tipsAnimation->setKeyValueAt(0, QRect(this->mapToGlobal(operationTipsBar->pos()), QSize(operationTipsBar->width(), 1)));
    tipsAnimation->setKeyValueAt(1.0, QRect(this->mapToGlobal(operationTipsBar->pos()), QSize(operationTipsBar->width(), operationTipsBar->height())));
    tipsAnimation->setDirection (QAbstractAnimation::Forward);
    if (tipsAnimation->state () != QAbstractAnimation::Running)
        tipsAnimation->start();*/
    tipsShowTimer.start(delay, this);
}

void MainWindow::onMassShakeBtnClicked()
{
    QList<VmInfo *> selectedVms = vmsGroupView->getSelectedVms();
    if (!selectedVms.count()) {
        MEmuMsgBox msgBox(tr("逍遥安卓"), tr("没有选中模拟器，请勾选后再操作！"), this);
        QPushButton *okBtn = msgBox.addButton(tr("确定"), QMessageBox::ActionRole);
        okBtn->setObjectName("dialogOkButton");
        msgBox.setCenterButtons(true);
        msgBox.exec2();
        msgBox.close();
        return;
    }

    MEmuMsgBox msgBox(tr("逍遥安卓"), tr("您确定对选中的逍遥安卓模拟器摇一摇吗？\n"), this);
    QPushButton *okBtn = msgBox.addButton(tr("Ok"), QMessageBox::ActionRole);
    QPushButton *quitBtn = msgBox.addButton("", QMessageBox::RejectRole);
    quitBtn->setFixedSize(0,0);
    msgBox.setCenterButtons(true);
    msgBox.exec2();
    msgBox.close();
    if (okBtn != msgBox.clickedButton())
        return;

    onShowOperationTips(tr("执行摇一摇中..."));
    this->groupsManager->groupVmsOperation(this->groupWidget->currentGroup(), "MEmuShake", "", selectedVms);
}

void MainWindow::onMassUseScriptBtnClicked()
{
    QList<VmInfo *> selectedVms = vmsGroupView->getSelectedVms();
    if (!selectedVms.count()) {
        MEmuMsgBox msgBox(tr("逍遥安卓"), tr("没有选中模拟器，请勾选后再操作！"), this);
        QPushButton *okBtn = msgBox.addButton(tr("确定"), QMessageBox::ActionRole);
        okBtn->setObjectName("dialogOkButton");
        msgBox.setCenterButtons(true);
        msgBox.exec2();
        msgBox.close();
        return;
    }

    OperationMsgBox msgBox(tr("逍遥安卓"), tr("请选择需要部署的逍遥脚本:\n"), this);
    QPushButton *okBtn = msgBox.addButton(tr("部署"), QMessageBox::AcceptRole);
    okBtn->setObjectName("dialogOkButton");
    okBtn->setFixedSize(78, 27);
    okBtn->setEnabled(false);
    msgBox.setCenterButtons(true);
    msgBox.exec2();
    bool isConfirmed = (msgBox.clickedButton() == okBtn);
    QString scriptFilePath = msgBox.inputLineEdit->text();
    msgBox.close();

    if (!isConfirmed)
        return;

    onShowOperationTips(tr("正在部署脚本%1...").arg(scriptFilePath));
    this->groupsManager->groupVmsOperation(this->groupWidget->currentGroup(), "ApplyOperationScript", scriptFilePath, selectedVms);
}

void MainWindow::onMassImportContactsBtnClicked()
{
    QList<VmInfo *> selectedVms = vmsGroupView->getSelectedVms();
    if (!selectedVms.count()) {
        MEmuMsgBox msgBox(tr("逍遥安卓"), tr("没有选中模拟器，请勾选后再操作！"), this);
        QPushButton *okBtn = msgBox.addButton(tr("确定"), QMessageBox::ActionRole);
        okBtn->setObjectName("dialogOkButton");
        msgBox.setCenterButtons(true);
        msgBox.exec2();
        msgBox.close();
        return;
    }

    OperationMsgBox msgBox(tr("逍遥安卓"), tr("请输入对当前组导入的联系人文件路径:\n"), this);
    QPushButton *okBtn = msgBox.addButton(tr("导入"), QMessageBox::AcceptRole);
    okBtn->setObjectName("dialogOkButton");
    okBtn->setFixedSize(78, 26);
    okBtn->setEnabled(false);
    msgBox.setCenterButtons(true);
    msgBox.exec2();
    bool isConfirmed = (msgBox.clickedButton() == okBtn);
    QString obexFilePath = msgBox.inputLineEdit->text();
    msgBox.close();

    if (!isConfirmed)
        return;

    onShowOperationTips(tr("正在导入联系人vcard文件%1...").arg(obexFilePath));
    this->groupsManager->groupVmsOperation(this->groupWidget->currentGroup(), "ImportContacts", obexFilePath, selectedVms);
}

void MainWindow::onMassModifySettingsBtnClicked()
{
    QList<VmInfo *> selectedVms = vmsGroupView->getSelectedVms();
    if (!selectedVms.count()) {
        MEmuMsgBox msgBox(tr("逍遥安卓"), tr("没有选中模拟器，请勾选后再操作！"), this);
        QPushButton *okBtn = msgBox.addButton(tr("确定"), QMessageBox::ActionRole);
        okBtn->setObjectName("dialogOkButton");
        msgBox.setCenterButtons(true);
        msgBox.exec2();
        msgBox.close();
        return;
    }

    ModifyVmPropertiesDialog modifySettingsDialog(this);
    modifySettingsDialog.exec2();
    if (modifySettingsDialog.result() != QDialog::Accepted)
        return;

    QList<QPair<QByteArray, QString> > result;
    modifySettingsDialog.getModifiedProperties(result);
    modifySettingsDialog.close();

    onShowOperationTips(tr("正在修改模拟器设置..."));

    for (int i = 0; i < result.count(); ++i) {
        QPair<QByteArray, QString> val = result.at(i);
        QString setting = QString(val.first) + "##" + val.second;
        this->groupsManager->groupVmsOperation(this->groupWidget->currentGroup(), "ModifyVmSetting", setting, selectedVms);
    }
}

void MainWindow::showServerVms()
{
    flushTimer.start(100, this);
}

void MainWindow::onAddPreviewWidget(VmInfo *itemData)
{
    if (!itemData)
        return;
    vmsMapView->addItem(itemData);
    vmsListView->addItem(itemData);
    //vmsGroupView->addItem(itemData);
}

void MainWindow::onRemovePreviewWidget(const char *ipaddr, const int vmPort)
{
    //vmsGroupView->removeItem(ipaddr, vmPort);
    vmsMapView->removeItem(ipaddr, vmPort);
    vmsListView->removeItem(ipaddr, vmPort);
/*    PreviewWidget *item = findItem(ipaddr, vmPort);
    if (item == NULL)
        return;

    gridViewLayout->removeWidget(item);
    subWinList.removeOne(item);

    //if (groupWidget->currentViewMode() != GroupWidget::VIEW_MODE_CUSTOM_GROUP ||
    //        groupWidget->currentGroup() != VM_GROUP_ALL )
    if (groupsManager->getGroupType(groupWidget->currentGroup()) == VM_GROUP_TYPE_HOST)
        delete item->data;

    item->setParent(NULL);
    delete item;
    if (lastHoverItem == item)
        lastHoverItem = NULL;
    item = NULL;
    //}

    if (currentPreviewMode() == PREVIEW_MODE_MAP)
        updateItemWidgets();
    else
        vmsInfoListView->removeItem(ipaddr, vmPort);*/
}

void MainWindow::onVmGroupChanged(int newGroup)
{        
/*    for (int i = 0; i < subWinList.count(); ) {
        PreviewWidget *pw = subWinList[i];
        this->gridViewLayout->removeWidget(pw);
        subWinList.removeOne(pw);
        delete pw;
        if (lastHoverItem == pw)
            lastHoverItem = NULL;
        pw = NULL;
    }
    subWinList.clear();*/

    QList<VmInfo *> vms = groupsManager->getVmsAsGroup(newGroup);
    //vmsGroupView->load(vms);
    vmsMapView->load(vms);
    vmsListView->load(vms);

    //vmsInfoListView->removeAll();
    //foreach (VmInfo *vm, vms)
    //    onAddPreviewWidget(vm);

    // set create button state

    if (groupWidget->currentViewMode() == GroupWidget::VIEW_MODE_HOST) {
        createBtn->show();
        addVmsToGroupBtn->hide();
        hSpacerLabel->show();
    } else if (groupWidget->currentGroup() == VM_GROUP_ALL) {
        createBtn->hide();
        addVmsToGroupBtn->hide();
        hSpacerLabel->hide();
    } else {
        createBtn->hide();
        addVmsToGroupBtn->show();
        hSpacerLabel->show();
    }
    return;
}

void MainWindow::onUpdatePreviewStatus(const char *ipaddr, const int vmPort, int newStatus)
{
    vmsMapView->onUpdatePreviewStatus(ipaddr, vmPort, newStatus);
    vmsListView->onRunningStatusChanged(ipaddr, vmPort, newStatus);
}

void VmsMapView::onUpdatePreviewStatus(const char *ipaddr, const int vmPort, int newStatus)
{
    PreviewWidget *item = findItem(ipaddr, vmPort);
    if (item == NULL)
        return;

    if (newStatus != MEMU_VM_STATUS_RUNNING &&
            newStatus != MEMU_VM_STATUS_LAUNCHED)
        item->operateWindowOnOff(false);
}

void MainWindow::timerEvent(QTimerEvent *event)
{
    if (event->timerId() == flushTimer.timerId()) {
        // Flush local clients for now
        vmsMapView->flushPreviewArea();
    } else if (event->timerId() == tipsShowTimer.timerId()) {
        operationTipsBar->hide();
        tipsShowTimer.stop();
    }
}

void MainWindow::removeItem(VmInfo *vm)
{
    if (!vm)
        return;

    bool isOnlyMapping = (groupWidget->currentViewMode() == GroupWidget::VIEW_MODE_CUSTOM_GROUP &&
            groupWidget->currentGroup() != VM_GROUP_ALL );

    if (isOnlyMapping)
        vmsGroupView->removeItem(vm->ipaddr, vm->vmPort);
    else {
        HostServer *sv = servers->getServer(vm->ipaddr, HOST_SERVER_PORT_LISTEN_ALL);
        if (!sv)
            return;
        emit sendCommand(sv->ipaddr, sv->consolePort,
                                    QString("RemoveVm##%1").arg(vm->vmName));
    }
}

void MainWindow::onUserAuthStateChanged(int authState)
{
    if (authState == USER_AUTH_STATE_FALSE) {
        setWindowVisible(false);
        UserAuthProcessDialog userAuthDialog(tr("逍遥群控助手"), tr("您还没有登录，请登录后使用！"), true, 0);
        userAuthDialog.exec2();
        userAuthDialog.close();
        if (userAuthDialog.result() == UserAuthProcessDialog::FLAG_LOGIN)
            showLoginDialog();
        else if (userAuthDialog.result() == UserAuthProcessDialog::FLAG_REGIST)
            showLoginDialog(LoginDialog::PHONE_REGISTER_WIDGET_INDEX);
        else {
            //force close mainwindow, if dialog closed by mannually
            this->close();
            exit(0);
            return;
        }
    } else if (authState == USER_AUTH_STATE_TRUE) {
        setWindowVisible(true);
        //this->show();
    }
}

void MainWindow::setWindowVisible(bool isVisible)
{
    if (this->isVisible() == isVisible)
        return;

    if (isVisible) {
        this->show();
        flushTimer.start(100, this);
    } else {
        this->show();
        flushTimer.stop();
    }
}

void VmsMapView::flushPreviewArea()
{
    foreach (PreviewWidget *item, subWinList) {
        // start the miracast
        if ((item->data->vmStatus == MEMU_VM_STATUS_LAUNCHED || item->data->vmStatus == MEMU_VM_STATUS_RUNNING) &&
                item->data->startMiracastRequest) {
            item->data->startMiracastRequest = false;
            item->onStartVmMiracast();
        }
        item->updateView();
    }
}

PreviewWidget *VmsMapView::getMouseOnItem(const QPoint &pos)
{
    QPoint itemsBasePos = this->mapTo(this, QPoint(0, 0));
    QPoint itemMapPoint = QPoint(pos.x() - itemsBasePos.x(), pos.y() - itemsBasePos.y());

    foreach (PreviewWidget *t, subWinList) {
        if (t->geometry().contains(itemMapPoint))
            return t;
    }
    return (PreviewWidget *)NULL;
}

void VmsMapView::mouseMoveEvent(QMouseEvent *event)
{
    if (w->currentPreviewMode() == PREVIEW_MODE_LIST)
        return QWidget::mouseMoveEvent(event);

    PreviewWidget *item = getMouseOnItem(event->pos());
    if (lastHoverItem != item) {
        if (lastHoverItem)
            lastHoverItem->setHoverAction(false);

        if (item)
            item->setHoverAction(true);

        lastHoverItem = item;
    }

    QWidget::mouseMoveEvent(event);
}

// change preview widget view for long term operation indication
void VmsMapView::addIndicatorPreviewWidget(const int taskId)
{
    PreviewWidget *pw = this->findIndicatorItem(taskId);
    if (pw)
        return;

    TaskData opTaskData;
    if (!w->tasksTrace->getTaskData(taskId, &opTaskData))
        return;

    currentOps = QString(opTaskData.commandline);
    //memset(currentOps, 0, sizeof(currentOps));
    //strncpy(currentOps, opTaskData.commandline.data(), sizeof(currentOps) - 1);

    if (opTaskData.commandline.contains("CloneVm") ||
            opTaskData.commandline.contains("CreateVm") ||
                opTaskData.commandline.contains("ImportVm")) {
        VmInfo *tempVm = new VmInfo (opTaskData.ipaddr, opTaskData.vmPort, "MEmuNext", MEMU_VM_STATUS_SHUTDOWN, NULL, taskId);
        //onAddPreviewWidget(tempVm);
        pw = new PreviewWidget(tempVm, QString("%1").arg(tempVm->getNameTag()), m_parent);
        pw->setBtnsEnabled(false, PreviewWidget::INDICATOR_ITEM);
        subWinList.append(pw);
        pw->show();
        updateItemWidgets();
    } else if (opTaskData.commandline.contains("InstallApk") ||
                opTaskData.commandline.contains("UninstallApk")) {
        pw = this->findItem(opTaskData.ipaddr, opTaskData.targetVmPort);
        if (!pw)
            return;
        pw->data->taskId = taskId;
    }

    QByteArray start = QByteArray("");
    QString cl = QString(opTaskData.commandline);
    pw->setStatusTips((int)VMC_INIT, start, cl);
}

void VmsMapView::cancelIndicatorPreviewWidget(const int taskId, int status, QByteArray backwords)
{
    PreviewWidget *pw = this->findIndicatorItem(taskId);
    if (!pw)
        return;
    qDebug() << "backwords!" << backwords << currentOps << status;
    // only operations failed can do this
    //pw->stopProgress((status != VMC_OPS_FAILED), backwords);
    pw->setStatusTips(status, backwords, currentOps);
    pw->data->taskId = INVALID_TASK_ID;

    if ((status != VMC_OK) && (currentOps.contains("CloneVm") ||
            currentOps.contains("CreateVm") ||
                currentOps.contains("ImportVm"))) {
        pw->setRemoveDelay(1000);
    }
}

void VmsMapView::updateIndicatorPreviewWidget(const int taskId, QByteArray backwords)
{
    PreviewWidget *pw = this->findIndicatorItem(taskId);
    if (!pw)
        return;

    // update progress of operation task
    if (backwords.isEmpty())
        return;
    bool ok;
    int progress = backwords.toInt(&ok);
    if (!ok)
        return;
    pw->setProgress(progress);
}

void MainWindow::onTaskStatusChanged(const int taskId, const int status, QByteArray backwords)
{
    if (status == VMC_OPS_FAILED || status == VMC_OK) {
        vmsMapView->updateItemStatus(taskId, status, backwords);
        vmsMapView->cancelIndicatorPreviewWidget(taskId, status, backwords);
        //vmsListView->cancelIndicatorPreviewWidget(taskId, status, backwords);
        emit removeTask(taskId);
    } else if (status == VMC_INIT) {
        vmsMapView->addIndicatorPreviewWidget(taskId);
        vmsMapView->updateItemStatus(taskId, status, backwords);
        //vmsListView->cancelIndicatorPreviewWidget(taskId, status, backwords);
    } else if (status == VMC_CONNECTED) {
        vmsMapView->updateIndicatorPreviewWidget(taskId, backwords);
        //vmsListView->cancelIndicatorPreviewWidget(taskId, status, backwords);
    }
    qDebug() << "add indcator ------" << taskId << status;
}

void VmsMapView::updateItemStatus(const int taskId, int status, QByteArray backwords)
{
    TaskData opTaskData;
    if (!w->tasksTrace->getTaskData(taskId, &opTaskData))
        return;

    if (opTaskData.commandline.contains("CloneVm")) {
        PreviewWidget *pw = NULL;
#if 0
        // update status of indicator
        pw = this->findIndicatorItem(taskId);
        if (pw) {
            QString newVmName = QString::fromLocal8Bit(backwords);
            //pw->data->vmPort = getVmPort(newVmName);
            pw->data->taskId = INVALID_TASK_ID;
            VmInfo newVm(opTaskData.ipaddr, getVmPort(newVmName), newVmName, MEMU_VM_STATUS_SHUTDOWN, NULL);
            w->vmsManager->addVm(newVm);
            pw->setBtnsEnabled(true, PreviewWidget::ALL_BTNS);
            //pw->data->vmName = newVmName;
            qDebug() << "[[[[[[[[" << pw->data->vmPort << newVmName;
        }
#endif
        // update status of vm which be cloned
        pw = findItem(opTaskData.ipaddr, opTaskData.targetVmPort);
        if (!pw)
            return;

        pw->setBtnsEnabled((status != VMC_INIT), PreviewWidget::ALL_BTNS);
        pw->setStatusMask((status != VMC_INIT) ? "" : tr("锁定中..."));
    } else {
    }
}

void MainWindow::createMassOpsBox()
{
    ui->bottomBox->setContentsMargins(0, 0, 0, 0);
    QHBoxLayout *massOpsBoxLayout = new QHBoxLayout(ui->bottomBox);
    massOpsBoxLayout->setMargin(0);

    massOpsBoxLayout->addSpacing(5);
    QToolBarMenuButton *massShakeBtn = new QToolBarMenuButton(tr("批量摇一摇"), this);
    massOpsBoxLayout->addSpacing(15);
    massOpsBoxLayout->addWidget(massShakeBtn);
    connect(massShakeBtn, SIGNAL(clicked()), this, SLOT(onMassShakeBtnClicked()));
    QToolBarMenuButton *massApplyScriptBtn = new QToolBarMenuButton(tr("批量部署脚本"), this);
    massOpsBoxLayout->addSpacing(15);
    massOpsBoxLayout->addWidget(massApplyScriptBtn);
    connect(massApplyScriptBtn, SIGNAL(clicked()), this, SLOT(onMassUseScriptBtnClicked()));
    QToolBarMenuButton *massImportContactsBtn = new QToolBarMenuButton(tr("批量导入联系人"), this);
    massOpsBoxLayout->addSpacing(15);
    massOpsBoxLayout->addWidget(massImportContactsBtn);
    connect(massImportContactsBtn, SIGNAL(clicked()), this, SLOT(onMassImportContactsBtnClicked()));
    QToolBarMenuButton *massModifySettingsBtn = new QToolBarMenuButton(tr("批量修改模拟器属性"), this);
    massOpsBoxLayout->addSpacing(15);
    massOpsBoxLayout->addWidget(massModifySettingsBtn);
    connect(massModifySettingsBtn, SIGNAL(clicked()), this, SLOT(onMassModifySettingsBtnClicked()));
    QToolBarMenuButton *groupLaunchBtn = new QToolBarMenuButton(tr("批量启动"), this, ":/button-launchvm.png");
    massOpsBoxLayout->addSpacing(15);
    massOpsBoxLayout->addWidget(groupLaunchBtn);
    connect(groupLaunchBtn, SIGNAL(clicked()), this, SLOT(onGroupLaunchBtnClicked()));
    QToolBarMenuButton *groupCloseBtn = new QToolBarMenuButton(tr("批量关闭"), this, ":/button-closevm.png");
    massOpsBoxLayout->addSpacing(15);
    massOpsBoxLayout->addWidget(groupCloseBtn);
    connect(groupCloseBtn, SIGNAL(clicked()), this, SLOT(onGroupCloseBtnClicked()));
    QToolBarMenuButton *groupInstallAppBtn = new QToolBarMenuButton(tr("批量安装APP"), this, ":/button-installapk.png");
    massOpsBoxLayout->addSpacing(15);
    massOpsBoxLayout->addWidget(groupInstallAppBtn);
    connect(groupInstallAppBtn, SIGNAL(clicked()), this, SLOT(onGroupInstallAppBtnClicked()));
    QToolBarMenuButton *groupUninstallAppBtn = new QToolBarMenuButton(tr("批量卸载APP"), this, ":/button-uninstallapk.png");
    massOpsBoxLayout->addSpacing(15);
    massOpsBoxLayout->addWidget(groupUninstallAppBtn);
    connect(groupUninstallAppBtn, SIGNAL(clicked()), this, SLOT(onGroupUninstallAppBtnClicked()));
    massOpsBoxLayout->addSpacing(20);
}

void MainWindow::onPreviewModeSwitched()
{
    QPushButton *clickedButton = qobject_cast<QPushButton *>(sender());
    bool checkedState = clickedButton->isChecked();
    if (clickedButton->objectName() == "btnListPreview")
        btnMapPreview->setChecked(!checkedState);
    else
        btnListPreview->setChecked(!checkedState);

    QList<VmInfo *> selectedVms = vmsGroupView->getSelectedVms();

    if (currentPreviewMode() == PREVIEW_MODE_MAP) {
        previewStackedWidget->setCurrentIndex(0);
        vmsGroupView = (PreviewAreaBase *)vmsMapView;
        //gridViewLayout->removeWidget(vmsListView);
        //vmsListView->setParent(NULL);
        //gridViewLayout->addWidget(vmsMapView, 0, 0, Qt::AlignCenter);
    } else {
        previewStackedWidget->setCurrentIndex(1);
        vmsGroupView = (PreviewAreaBase *)vmsListView;
        //gridViewLayout->removeWidget(vmsMapView);
        //vmsMapView->setParent(NULL);
        //gridViewLayout->addWidget(vmsListView, 0, 0, Qt::AlignCenter);

    }
    // sync selected state
    QList<VmInfo *> vms = groupsManager->getVmsAsGroup(groupWidget->currentGroup());
    foreach (VmInfo *vm, vms)
        vmsGroupView->setSelected(vm->ipaddr, vm->vmPort, selectedVms.contains(vm));
}

int MainWindow::currentPreviewMode()
{
    return (btnMapPreview->isChecked()) ? PREVIEW_MODE_MAP : PREVIEW_MODE_LIST;
}

void MainWindow::onSetSelectAll(void)
{
    vmsGroupView->selectAll();
}

void MainWindow::onTipsBarCloseBtnClicked(void)
{
    operationTipsBar->hide();
}

void MainWindow::hideAniomationFinished ()
{
    QWidget::setVisible (false);
    disconnect (tipsAnimation, SIGNAL (finished ()),
                this, SLOT (hideAniomationFinished ()));
}

void MainWindow::setWindowPos(QPoint pos)
{
    move(pos);
}

void MainWindow::slotClose()
{
    MEmuMsgBox msgBox (tr("关闭逍遥群控助手"), tr("关闭逍遥群控助手，所有已打开窗口也将关闭！"), w);
    msgBox.setStyleSheet("color: black;font: 12px \"Microsoft Yahei\";");
    QPushButton *okBtn = msgBox.addButton(tr("确定"), QMessageBox::AcceptRole);
    okBtn->setDefault(false);
    QPushButton *quitBtn = msgBox.addButton(tr("取消"), QMessageBox::RejectRole);
    quitBtn->setDefault(true);
    msgBox.setCenterButtons(true);
    msgBox.exec2();
    bool isConfirmed = (msgBox.clickedButton() == okBtn);
    msgBox.close();
    if (!isConfirmed)
        return;
    this->close();
    exit(0);
    return;
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    vmsMapView->updateItemWidgets();
    QMainWindow::resizeEvent(event);
}

int MainWindow::getPreviewAreaWidth()
{
    int border = 1;
    //return ui->gridViewWidget->width() - 2*border;
    return previewStackedWidget->width() - 2*border;
}

/*
*/
GroupPreviewData::GroupPreviewData (QList<VmInfo*> &s_vms, QObject *parent)
    : QObject (parent)
    , vms(s_vms)
{
}

PreviewAreaBase::PreviewAreaBase (QWidget *parent)
    : QWidget(parent)
    //, m_data(data)
{
}

QList<VmInfo *> PreviewAreaBase::getSelectedVms(bool){}
void PreviewAreaBase::setSelected(const char *ipaddr, const int vmPort, bool isSelected) {}
bool PreviewAreaBase::selected(const char *ipaddr, const int vmPort) {}
void PreviewAreaBase::load(QList<VmInfo *> &vms){}
void PreviewAreaBase::removeAll(){}
void PreviewAreaBase::removeItem(const char *ipaddr, const int vmPort){}
void PreviewAreaBase::addItem(VmInfo *vm){}
void PreviewAreaBase::updateItem(VmInfo *vm){}

VmsMapView::VmsMapView(QWidget *parent)
    : PreviewAreaBase(parent)
    , m_parent((MainWindow *)parent)
{
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    this->setContentsMargins(0, 0, 0, 0);
    subWinList.clear();
    lastHoverItem = NULL;

    gridViewLayout = new QGridLayout(this);
    QSpacerItem *horizontalSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Maximum);
    gridViewLayout->addItem(horizontalSpacer, 0, 0, 1, NR_COL);

    QPalette scrollAreaBgpal2 = this->palette();
    scrollAreaBgpal2.setColor (QPalette::Window, QColor(255, 255, 255));
    this->setPalette(scrollAreaBgpal2);

    currentOps.clear();
    //memset(currentOps, 0, sizeof(currentOps));
}

VmsMapView::~VmsMapView()
{}

QList<VmInfo *> VmsMapView::getSelectedVms(bool selectRunningVm)
{
    QList<VmInfo *> items;
    foreach (PreviewWidget *item, subWinList) {
        if (!item->isSelected())
            continue;
        if (selectRunningVm && item->data->vmStatus != MEMU_VM_STATUS_LAUNCHED)
            continue;
        items.append(item->data);
    }

    return items;
}

void VmsMapView::setSelected(const char *ipaddr, const int vmPort, bool isSelected)
{
    PreviewWidget *item = findItem(ipaddr, vmPort);
    if (item == NULL)
        return;
    item->setSelected(isSelected);
}

bool VmsMapView::selected(const char *ipaddr, const int vmPort)
{
    PreviewWidget *item = findItem(ipaddr, vmPort);
    if (item == NULL)
        return false;
    return item->isSelected();
}

void VmsMapView::load(QList<VmInfo *> &vms)
{
    removeAll();
    foreach (VmInfo *vm, vms)
        addItem(vm);
    updateItemWidgets();
}

void VmsMapView::removeAll()
{
    for (int i = 0; i < subWinList.count(); ) {
        PreviewWidget *pw = subWinList[i];
        this->gridViewLayout->removeWidget(pw);
        subWinList.removeOne(pw);
        delete pw;
        if (lastHoverItem == pw)
            lastHoverItem = NULL;
        pw = NULL;
    }
    subWinList.clear();
}

void VmsMapView::updateItemWidgets(void)
{
    int width = w->getPreviewAreaWidth();
    //if (this->width() < ITEM_WIDTH)
    //    return;

    this->setFixedWidth(width);

    int marginleft, margintop, marginright, marginbottom;
    gridViewLayout->getContentsMargins(&marginleft, &margintop, &marginright, &marginbottom);
    int mainspacing = gridViewLayout->spacing();
    int height = 0;
    // calculate column number
    int size = subWinList.size();
    int MAX_NR_COL = (this->width() - marginleft - marginright) / ITEM_WIDTH;
    MAX_NR_COL = (width < MAX_NR_COL * ITEM_WIDTH + (MAX_NR_COL-1) * mainspacing + marginleft + marginright) ?
                (MAX_NR_COL - 1) : MAX_NR_COL;
    MAX_NR_COL = MAX_NR_COL ? MAX_NR_COL : 1;
    int rows = size/MAX_NR_COL + ((size%MAX_NR_COL) ? 1 : 0);
    int j = MAX_NR_COL;

    for (int i = 0; i < rows; ++i) {
         for (j = 0; j < MAX_NR_COL; ++j) {
             int index = i*MAX_NR_COL+j;
             if (index >= size)
                 break;

             gridViewLayout->addWidget(subWinList.at(index), i, j, Qt::AlignCenter);
         }
    }

    // update size
    height += rows * ITEM_HEIGHT + margintop + marginbottom + (rows - 1)*mainspacing;
    height = (height < 0) ? 0 : height;
    gridViewLayout->activate();
    this->setFixedHeight(height);

    update();
}

void VmsMapView::removeItem(const char *ipaddr, const int vmPort)
{
    PreviewWidget *item = findItem(ipaddr, vmPort);
    if (item == NULL)
        return;

    gridViewLayout->removeWidget(item);
    subWinList.removeOne(item);

    QList<VmInfo *> rv;
    w->groupsManager->removeVms(w->groupWidget->currentGroup(), rv << item->data);

    if (w->groupsManager->getGroupType(w->groupWidget->currentGroup()) == VM_GROUP_TYPE_HOST ||
            w->groupWidget->currentGroup() == VM_GROUP_ALL) {
        delete item->data;
        item->data = NULL;
    }

    item->setParent(NULL);
    delete item;
    if (lastHoverItem == item)
        lastHoverItem = NULL;
    item = NULL;

    updateItemWidgets();

}

void VmsMapView::addItem(VmInfo *itemData)
{
    if (!itemData)
        return;
    qDebug() << "additem" << itemData->taskId << itemData->vmName;
    // if has indicator preview widget, than replace it's data by the real itemData
    PreviewWidget *item = findIndicatorItem(itemData->taskId);
    if (item) {
        qDebug() << "replace" << itemData->taskId << itemData->vmName;
        VmInfo *oldData = item->data;
        item->data = itemData;
        item->data->taskId = INVALID_TASK_ID;
        delete oldData;
        item->setDescriptText(tr("%1").arg(item->data->getNameTag()));
        //item->stopProgress(true);
        QByteArray end = QByteArray("");
        item->setStatusTips((int)VMC_OK, end, currentOps);
        item->setBtnsEnabled(true, PreviewWidget::ALL_BTNS);
        return;
    }

    item = findItem(itemData->ipaddr, itemData->vmPort);
    if (item != NULL)
        return;

    PreviewWidget *newWin = new PreviewWidget(itemData, QString("%1").arg(itemData->getNameTag()), m_parent);
    subWinList.append(newWin);
    qSort(subWinList.begin(), subWinList.end());
    newWin->show();
    updateItemWidgets();
}

void VmsMapView::updateItem(VmInfo *vm)
{}

void VmsMapView::onSelectedVmChanged(QList<VmInfo *> &)
{}

PreviewWidget *VmsMapView::findItem(const char *ipaddr, int vmPort)
{
    foreach (PreviewWidget *subWin, subWinList) {
        if (strcmp(subWin->data->ipaddr, ipaddr) || subWin->data->vmPort != vmPort)
            continue;
        return subWin;
    }

    return NULL;
}

PreviewWidget *VmsMapView::findIndicatorItem(const int taskId)
{
    if (taskId == INVALID_TASK_ID)
        return NULL;

    foreach (PreviewWidget *subWin, subWinList) {
        if (subWin->data->taskId == INVALID_TASK_ID || subWin->data->taskId != taskId)
            continue;
        return subWin;
    }

    return NULL;
}

void VmsMapView::selectAll()
{
    QList<VmInfo *> itemList = this->getSelectedVms();
    bool isSelectedAll = (itemList.count() == subWinList.count());

    foreach (PreviewWidget *item, subWinList)
        item->setSelected(!isSelectedAll);
}

#define VM_RUNNING_STATUS(status) ((status == MEMU_VM_STATUS_RUNNING) ? tr("启动中") : \
    ((status == MEMU_VM_STATUS_LAUNCHED) ? tr("运行中") : tr("已关闭")))

VmsListView::VmsListView(QWidget *parent)
    : PreviewAreaBase(parent)
{
    predefines <<tr("名称")<<tr("IP")<<tr("端口")<<tr("运行状态")<<tr("CPU数")<< tr("内存大小");
    m_view = new QTableView(this);
    m_view->horizontalHeader()->setStretchLastSection(true);
    m_view->verticalHeader()->setHidden(true);
    m_view->setColumnWidth(0, 165);
    //m_view->setEditTriggers(QTableView::NoEditTriggers);
    m_view->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_view->setAlternatingRowColors(true);

    m_model = new QStandardItemModel;
    m_model->setColumnCount(predefines.count());
    for (int col = 0; col < predefines.count(); col ++)
        m_model->setHeaderData(col, Qt::Horizontal, predefines[col]);
    m_view->setModel(m_model);
    m_model->sort(2, Qt::AscendingOrder);

    QGridLayout *layout = new QGridLayout(this);
    layout->addWidget(m_view);
    layout->setMargin(0);
    layout->setSpacing(0);
    this->setContentsMargins(0, 0, 0, 0);
}

VmsListView::~VmsListView()
{}

QList<VmInfo *> VmsListView::getSelectedVms(bool selectRunningVm)
{
    QList<VmInfo *> items;
    for (int i = 0; i < m_model->rowCount(); ++i) {
        QStandardItem *item = m_model->item(i, 0);
        if (item->checkState() != Qt::Checked)
            continue;
        uint vmptr = m_model->data(m_model->index(i, 0), Qt::UserRole).toUInt();
        VmInfo *vm = (VmInfo *)vmptr;
        if (vm) {
            if (selectRunningVm && vm->vmStatus != MEMU_VM_STATUS_LAUNCHED)
                continue;
            items.append(vm);
        }
    }
    return items;
}

void VmsListView::load(QList<VmInfo *> &vms)
{
    removeAll();
    foreach (VmInfo *vm, vms)
        addItem(vm);
}

void VmsListView::addItem(VmInfo *vm)
{
    if (findItem(vm->ipaddr, vm->vmPort) != -1)
        return;

    int row = m_model->rowCount();

    if (!m_model->insertRow(row))
        return;

    m_model->setData(m_model->index(row, 0), vm->vmName, Qt::EditRole);
    m_model->setData(m_model->index(row, 1), vm->ipaddr, Qt::EditRole);
    m_model->setData(m_model->index(row, 2), vm->vmPort, Qt::EditRole);
    m_model->setData(m_model->index(row, 3), VM_RUNNING_STATUS(vm->vmStatus), Qt::EditRole);
    m_model->setData(m_model->index(row, 4), vm->vmSetting.vmCpuNum, Qt::EditRole);
    m_model->setData(m_model->index(row, 5), vm->vmSetting.vmMemSize, Qt::EditRole);

    QStandardItem *item = m_model->item(row, 0);
    item->setCheckable(true);
    item->setEditable(false);
    item->setCheckState(Qt::Unchecked);
    uint vmptr = (uint)vm;
    item->setData(vmptr, Qt::UserRole);
    item = m_model->item(row, 1);
    item->setEditable(false);
    item = m_model->item(row, 2);
    item->setEditable(false);
}

void VmsListView::onSelectedVmChanged(QList<VmInfo *> &vms)
{}

void VmsListView::removeItem(const char *ipaddr, const int vmPort)
{
    int row = findItem(ipaddr, vmPort);
    m_model->removeRow(row);
}

void VmsListView::removeAll(void)
{
    int count = m_model->rowCount();
    m_model->removeRows(0, count);
}

void VmsListView::updateItem(VmInfo *data)
{
}

void VmsListView::onRunningStatusChanged(const char *ipaddr, const int vmPort, int vmStatus)
{
    int row = findItem(ipaddr, vmPort);
    m_model->setData(m_model->index(row, 3), VM_RUNNING_STATUS(vmStatus), Qt::DisplayRole);
}

void VmsListView::setSelected(const char *ipaddr, const int vmPort, bool isSelected)
{
    int row = findItem(ipaddr, vmPort);
    QStandardItem *item = m_model->item(row, 0);
    if (item)
        item->setCheckState(isSelected ? Qt::Checked : Qt::Unchecked);
}

bool VmsListView::selected(const char *ipaddr, const int vmPort)
{
    int row = findItem(ipaddr, vmPort);
    QStandardItem *item = m_model->item(row, 0);
    if (!item)
        return false;
    return (item->checkState() == Qt::Checked);
}

int VmsListView::findItem(const char *ipaddr, const int vmPort)
{
    for (int i = 0; i < m_model->rowCount(); ++i) {
        QByteArray itemIpaddr = m_model->data(m_model->index(i, 1), Qt::EditRole).toByteArray();
        int itemVmPort = m_model->data(m_model->index(i, 2), Qt::EditRole).toInt();
        if (!strcmp(itemIpaddr.data(), ipaddr) && itemVmPort == vmPort)
            return i;
    }
    return -1;
}

void VmsListView::selectAll()
{
    QList<VmInfo *> itemList = this->getSelectedVms();
    bool isSelectedAll = (itemList.count() == m_model->rowCount());

    for (int i = 0; i < m_model->rowCount(); ++i) {
        QByteArray itemIpaddr = m_model->data(m_model->index(i, 1), Qt::EditRole).toByteArray();
        int itemVmPort = m_model->data(m_model->index(i, 2), Qt::EditRole).toInt();
        this->setSelected(itemIpaddr, itemVmPort, !isSelectedAll);
    }
    return;
}
